{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class Animal():\n",
    "    def __init__(self,name,weight):\n",
    "        self.name = name\n",
    "        self.weight = weight\n",
    "    def print_weight(self):\n",
    "        print(\"%s : %s\" % (self.name,self.weight))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "dog = Animal('hasky',90)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "90\n",
      "100\n"
     ]
    }
   ],
   "source": [
    "print(dog.weight) #90\n",
    "dog.weight = 100\n",
    "print(dog.weight) #100"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hasky : 90\n"
     ]
    }
   ],
   "source": [
    "class Animal():\n",
    "    def __init__(self,name,weight):\n",
    "        self.name = name\n",
    "        self.weight = weight\n",
    "    def print_weight(self):\n",
    "        print(\"%s : %s\" % (self.name,self.weight))\n",
    "\n",
    "dog = Animal('hasky',90)\n",
    "dog.print_weight() # hasky : 90"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hasky\n"
     ]
    },
    {
     "ename": "AttributeError",
     "evalue": "'Animal' object has no attribute '__name'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-13-b6aba6167e0d>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     16\u001b[0m \u001b[0mdog\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mAnimal\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'hasky'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m90\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     17\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdog\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_name\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# hasky\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 18\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdog\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__name\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# 'Animal' object has no attribute '__name'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     19\u001b[0m \u001b[0mdog\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_weight\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m100\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     20\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdog\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_weight\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# 100\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mAttributeError\u001b[0m: 'Animal' object has no attribute '__name'"
     ]
    }
   ],
   "source": [
    "class Animal():\n",
    "    def __init__(self,name,weight):\n",
    "        self.__name = name\n",
    "        self.__weight = weight\n",
    "    def print_weight(self):\n",
    "        print(\"%s : %s\" % (self.name,self.weight))\n",
    "    def get_name(self):\n",
    "        return self.__name\n",
    "    def get_weight(self):\n",
    "        return self.__weight\n",
    "    def set_name(self,name):\n",
    "        self.__name = name\n",
    "    def set_weight(self,weight):\n",
    "        self.__weight = weight\n",
    "\n",
    "dog = Animal('hasky',90)\n",
    "print(dog.get_name()) # hasky\n",
    "print(dog.__name) # AttributeError: 'Animal' object has no attribute '__name'\n",
    "dog.set_weight(100)\n",
    "print(dog.get_weight()) # 100\n",
    "print(dog.__weight) # AttributeError: 'Animal' object has no attribute '__weight'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'_Animal__name': 'hasky', '_Animal__weight': 90}"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dog.__dict__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Animal is running\n",
      "Dog is eating\n",
      "Cat is running\n"
     ]
    }
   ],
   "source": [
    "class Animal():\n",
    "    def __init__(self,name,weight):\n",
    "        self.name = name\n",
    "        self.weight = weight\n",
    "    def print_weight(self):\n",
    "        print(\"%s : %s\" % (self.name,self.weight))\n",
    "    def run(self):\n",
    "        print('Animal is running')\n",
    "\n",
    "class Dog(Animal):\n",
    "    def eat(self):\n",
    "        print('Dog is eating')\n",
    "class Cat(Animal):\n",
    "    def run(self):\n",
    "        print('Cat is running')\n",
    "\n",
    "dog = Dog('hasky',10)\n",
    "dog.run() # Animal is running\n",
    "dog.eat() # Dog is eating\n",
    "cat = Cat('tt',20)\n",
    "cat.run() # Cat is running"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'hasky'"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class Animal():\n",
    "    def __init__(self,name,weight):\n",
    "        self.name = name\n",
    "        self.weight = weight\n",
    "    def print_weight(self):\n",
    "        print(\"%s : %s\" % (self.name,self.weight))\n",
    "    def run(self):\n",
    "        print('Animal is running')\n",
    "\n",
    "class Dog(Animal):\n",
    "    def __init__(self,name,weight,height):\n",
    "        super().__init__(name,weight)\n",
    "        self.height = height\n",
    "    def eat(self):\n",
    "        print('Dog is eating')\n",
    "\n",
    "dog = Dog('hasky',10,20)\n",
    "dog.name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n",
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "class Animal():\n",
    "    def __init__(self,name,weight):\n",
    "        self.name = name\n",
    "        self.weight = weight\n",
    "    def print_weight(self):\n",
    "        print(\"%s : %s\" % (self.name,self.weight))\n",
    "    def run(self):\n",
    "        print('Animal is running')\n",
    "\n",
    "class Dog(Animal):\n",
    "    def eat(self):\n",
    "        print('Dog is eating')\n",
    "\n",
    "a = Dog(\"hasky\",90)\n",
    "b = Animal('tt',10)\n",
    "print(isinstance(a,Dog))# True\n",
    "print(isinstance(a,Animal))# True\n",
    "print(isinstance(b,Animal))# True\n",
    "print(isinstance(b,Dog))# False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Animal is running\n",
      "Animal is running\n",
      "Animal is running\n",
      "Animal is running\n"
     ]
    }
   ],
   "source": [
    "def run_twice(obj):\n",
    "    obj.run()\n",
    "    obj.run()\n",
    "\n",
    "a = Dog(\"hasky\",90)\n",
    "b = Animal('tt',10)\n",
    "run_twice(a)\n",
    "run_twice(b)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "start....\n",
      "start....\n"
     ]
    }
   ],
   "source": [
    "class Timer(object):\n",
    "    def run(self):\n",
    "        print('start....')\n",
    "\n",
    "timer = Timer()\n",
    "run_twice(timer)\n",
    "# start....\n",
    "# start...."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['__add__',\n",
       " '__class__',\n",
       " '__contains__',\n",
       " '__delattr__',\n",
       " '__dir__',\n",
       " '__doc__',\n",
       " '__eq__',\n",
       " '__format__',\n",
       " '__ge__',\n",
       " '__getattribute__',\n",
       " '__getitem__',\n",
       " '__getnewargs__',\n",
       " '__gt__',\n",
       " '__hash__',\n",
       " '__init__',\n",
       " '__init_subclass__',\n",
       " '__iter__',\n",
       " '__le__',\n",
       " '__len__',\n",
       " '__lt__',\n",
       " '__mod__',\n",
       " '__mul__',\n",
       " '__ne__',\n",
       " '__new__',\n",
       " '__reduce__',\n",
       " '__reduce_ex__',\n",
       " '__repr__',\n",
       " '__rmod__',\n",
       " '__rmul__',\n",
       " '__setattr__',\n",
       " '__sizeof__',\n",
       " '__str__',\n",
       " '__subclasshook__',\n",
       " 'capitalize',\n",
       " 'casefold',\n",
       " 'center',\n",
       " 'count',\n",
       " 'encode',\n",
       " 'endswith',\n",
       " 'expandtabs',\n",
       " 'find',\n",
       " 'format',\n",
       " 'format_map',\n",
       " 'index',\n",
       " 'isalnum',\n",
       " 'isalpha',\n",
       " 'isdecimal',\n",
       " 'isdigit',\n",
       " 'isidentifier',\n",
       " 'islower',\n",
       " 'isnumeric',\n",
       " 'isprintable',\n",
       " 'isspace',\n",
       " 'istitle',\n",
       " 'isupper',\n",
       " 'join',\n",
       " 'ljust',\n",
       " 'lower',\n",
       " 'lstrip',\n",
       " 'maketrans',\n",
       " 'partition',\n",
       " 'replace',\n",
       " 'rfind',\n",
       " 'rindex',\n",
       " 'rjust',\n",
       " 'rpartition',\n",
       " 'rsplit',\n",
       " 'rstrip',\n",
       " 'split',\n",
       " 'splitlines',\n",
       " 'startswith',\n",
       " 'strip',\n",
       " 'swapcase',\n",
       " 'title',\n",
       " 'translate',\n",
       " 'upper',\n",
       " 'zfill']"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dir('ABC')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "print('ABC'.__len__())\n",
    "print(len('ABC'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "20\n"
     ]
    }
   ],
   "source": [
    "class Animal():\n",
    "    def __init__(self,name,weight):\n",
    "        self.name = name\n",
    "        self.weight = weight\n",
    "    def print_weight(self):\n",
    "        print(\"%s : %s\" % (self.name,self.weight))\n",
    "    def run(self):\n",
    "        print('Animal is running')\n",
    "\n",
    "dog = Animal('hasky',20)\n",
    "print(hasattr(dog,'name')) # True\n",
    "setattr(dog,'height',20)\n",
    "print(getattr(dog,'height')) # 20"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dog\n"
     ]
    }
   ],
   "source": [
    "print(getattr(dog,'type','dog')) #dog"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<bound method Animal.run of <__main__.Animal object at 0x104f33cc0>>\n",
      "Animal is running\n"
     ]
    }
   ],
   "source": [
    "f = getattr(dog,'run')\n",
    "print(f) # <bound method Animal.run of <__main__.Animal object at 0x104f33cc0>>\n",
    "f() # Animal is running"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "20\n"
     ]
    }
   ],
   "source": [
    "class Animal():\n",
    "    def __init__(self,name,weight):\n",
    "        self.name = name\n",
    "        self.weight = weight\n",
    "dog = Animal('hasky',90)\n",
    "dog.height = 20 \n",
    "print(dog.height) # 20"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ss\n",
      "ss\n",
      "aa\n",
      "ss\n"
     ]
    }
   ],
   "source": [
    "class Animal():\n",
    "    tt = 'ss'\n",
    "    def __init__(self,name,weight):\n",
    "        self.name = name\n",
    "        self.weight = weight\n",
    "print(Animal.tt) # ss\n",
    "dog = Animal('hasky',90) \n",
    "print(dog.tt) # ss\n",
    "dog.tt = 'aa'\n",
    "print(dog.tt) # aa\n",
    "print(Animal.tt)# ss"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "20\n"
     ]
    }
   ],
   "source": [
    "class Animal():\n",
    "    pass\n",
    "\n",
    "ani = Animal()\n",
    "ani.name = 'hasky'\n",
    "\n",
    "from types import MethodType\n",
    "def set_age(self,age):\n",
    "    self.age = age\n",
    "\n",
    "ani.set_age = MethodType(set_age,ani)\n",
    "ani.set_age(20)\n",
    "print(ani.age) #20 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "ename": "AttributeError",
     "evalue": "'Animal' object has no attribute 'set_age'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-48-3dee81caeeaa>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[0mani2\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mAnimal\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      2\u001b[0m \u001b[0;31m#print(ani2.name) # AttributeError: 'Animal' object has no attribute 'name'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mani2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_age\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m20\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m: 'Animal' object has no attribute 'set_age'"
     ]
    }
   ],
   "source": [
    "ani2 = Animal()\n",
    "print(ani2.name) # AttributeError: 'Animal' object has no attribute 'name'\n",
    "ani2.set_age(20) # AttributeError: 'Animal' object has no attribute 'set_age'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "20\n"
     ]
    }
   ],
   "source": [
    "Animal.set_age = set_age\n",
    "ani2.set_age(20)\n",
    "print(ani2.age) # 20"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "ename": "AttributeError",
     "evalue": "'Animal' object has no attribute 'height'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-51-7e68d06a99b8>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0mani\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'hasky'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      6\u001b[0m \u001b[0mani\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mweight\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m90\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 7\u001b[0;31m \u001b[0mani\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mheight\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m20\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m: 'Animal' object has no attribute 'height'"
     ]
    }
   ],
   "source": [
    "class Animal():\n",
    "    __slots__ = ['name','weight']\n",
    "    \n",
    "ani = Animal()\n",
    "ani.name = 'hasky'\n",
    "ani.weight = 90\n",
    "ani.height = 20 # AttributeError: 'Animal' object has no attribute 'height'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "20\n"
     ]
    }
   ],
   "source": [
    "class Dog(Animal):\n",
    "    pass\n",
    "dog = Dog()\n",
    "dog.height = 20\n",
    "print(dog.height) # 20"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "60\n"
     ]
    },
    {
     "ename": "ValueError",
     "evalue": "weight must between 1 ~ 200!",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-54-25af3c0b5625>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     13\u001b[0m \u001b[0mani\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_weight\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m60\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     14\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mani\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_weight\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 15\u001b[0;31m \u001b[0mani\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_weight\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m999\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;32m<ipython-input-54-25af3c0b5625>\u001b[0m in \u001b[0;36mset_weight\u001b[0;34m(self, value)\u001b[0m\n\u001b[1;32m      8\u001b[0m             \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'weight must be an integer!'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      9\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mvalue\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;36m1\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mvalue\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m200\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 10\u001b[0;31m             \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'weight must between 1 ~ 200!'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     11\u001b[0m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mweight\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     12\u001b[0m \u001b[0mani\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mAnimal\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mValueError\u001b[0m: weight must between 1 ~ 200!"
     ]
    }
   ],
   "source": [
    "class Animal(object):\n",
    "\n",
    "    def get_weight(self):\n",
    "         return self.weight\n",
    "\n",
    "    def set_weight(self, value):\n",
    "        if not isinstance(value, int):\n",
    "            raise ValueError('weight must be an integer!')\n",
    "        if value < 1 or value > 200:\n",
    "            raise ValueError('weight must between 1 ~ 200!')\n",
    "        self.weight = value\n",
    "ani = Animal()\n",
    "ani.set_weight(60)\n",
    "print(ani.get_weight()) # 60\n",
    "ani.set_weight(999) # ValueError: weight must between 1 ~ 200!\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "60\n"
     ]
    },
    {
     "ename": "ValueError",
     "evalue": "weight must between 1 ~ 200!",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-58-d7e6d566089d>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     15\u001b[0m \u001b[0mani\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mweight\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m60\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     16\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mani\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mweight\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 17\u001b[0;31m \u001b[0mani\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mweight\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m999\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;32m<ipython-input-58-d7e6d566089d>\u001b[0m in \u001b[0;36mweight\u001b[0;34m(self, value)\u001b[0m\n\u001b[1;32m      9\u001b[0m             \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'weight must be an integer!'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     10\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0mvalue\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;36m1\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mvalue\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m200\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 11\u001b[0;31m             \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'weight must between 1 ~ 200!'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     12\u001b[0m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_weight\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mvalue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     13\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mValueError\u001b[0m: weight must between 1 ~ 200!"
     ]
    }
   ],
   "source": [
    "class Animal(object):\n",
    "    @property\n",
    "    def weight(self):\n",
    "         return self._weight\n",
    "        \n",
    "    @weight.setter\n",
    "    def weight(self, value):\n",
    "        if not isinstance(value, int):\n",
    "            raise ValueError('weight must be an integer!')\n",
    "        if value < 1 or value > 200:\n",
    "            raise ValueError('weight must between 1 ~ 200!')\n",
    "        self._weight = value\n",
    "        \n",
    "ani = Animal()\n",
    "ani.weight = 60\n",
    "print(ani.weight) # 60\n",
    "ani.weight = 999 #  ValueError: weight must between 1 ~ 200!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "60\n"
     ]
    }
   ],
   "source": [
    "class Animal(object):\n",
    "    @property\n",
    "    def birth(self):\n",
    "         return self._birth\n",
    "        \n",
    "    @birth.setter\n",
    "    def birth(self, value):\n",
    "        if not isinstance(value, int):\n",
    "            raise ValueError('birth must be an integer!')\n",
    "        if value < 1 or value > 2018:\n",
    "            raise ValueError('birth must between 1 ~ 2018!')\n",
    "        self._birth = value\n",
    "    \n",
    "    @property\n",
    "    def age(self):\n",
    "        return 2018 - self._birth\n",
    "        \n",
    "ani = Animal()\n",
    "ani.birth = 1958\n",
    "print(ani.age) # 60"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<__main__.Animal object at 0x104fccd68>\n"
     ]
    }
   ],
   "source": [
    "print(ani) # <__main__.Animal object at 0x104fccd68>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Animal object with name : tt\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<__main__.Animal at 0x104e8ecf8>"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "class Animal(object):\n",
    "    def __init__(self,name):\n",
    "        self.name = name\n",
    "    def __str__(self):\n",
    "        return 'Animal object with name : %s' % self.name\n",
    "print(Animal('tt')) # Animal object with name : tt\n",
    "a = Animal('tt')\n",
    "a # <__main__.Animal at 0x104e8ecf8>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "1\n",
      "2\n",
      "3\n",
      "5\n",
      "8\n"
     ]
    }
   ],
   "source": [
    "class Fib(object):\n",
    "    def __init__(self):\n",
    "        self.a, self.b = 0, 1 # 初始化两个计数器a，b\n",
    "\n",
    "    def __iter__(self):\n",
    "        return self # 实例本身就是迭代对象，故返回自己\n",
    "\n",
    "    def __next__(self):\n",
    "        self.a, self.b = self.b, self.a + self.b # 计算下一个值\n",
    "        if self.a > 10: # 退出循环的条件\n",
    "            raise StopIteration()\n",
    "        return self.a # 返回下一个值\n",
    "for n in Fib():\n",
    "    print(n)\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[2, 3, 5]\n",
      "89\n"
     ]
    }
   ],
   "source": [
    "class Fib(object):\n",
    "    def __getitem__(self, n):\n",
    "        if isinstance(n, int): # n是索引\n",
    "            a, b = 1, 1\n",
    "            for x in range(n):\n",
    "                a, b = b, a + b\n",
    "            return a\n",
    "        if isinstance(n, slice): # n是切片\n",
    "            start = n.start\n",
    "            stop = n.stop\n",
    "            if start is None:\n",
    "                start = 0\n",
    "            a, b = 1, 1\n",
    "            L = []\n",
    "            for x in range(stop):\n",
    "                if x >= start:\n",
    "                    L.append(a)\n",
    "                a, b = b, a + b\n",
    "            return L\n",
    "f = Fib()\n",
    "print(f[2:5]) # [1, 1, 2, 3, 5]\n",
    "print(f[10]) # 89"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "20\n"
     ]
    }
   ],
   "source": [
    "class Animal():\n",
    "    def __init__(self,name,weight):\n",
    "        self.name = name\n",
    "        self.weight = weight\n",
    "    def __getattr__(self,attr):\n",
    "        if attr == 'height':\n",
    "            return 20\n",
    "a = Animal(\"hasky\",90)\n",
    "print(a.height) # 20"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "20\n",
      "25\n"
     ]
    }
   ],
   "source": [
    "class Animal():\n",
    "    def __init__(self,name,weight):\n",
    "        self.name = name\n",
    "        self.weight = weight\n",
    "    def __getattr__(self,attr):\n",
    "        if attr == 'height':\n",
    "            return 20\n",
    "        elif attr == 'age':\n",
    "            return lambda: 25\n",
    "a = Animal(\"hasky\",90)\n",
    "print(a.height) # 20\n",
    "print(a.age()) # 25"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "ename": "AttributeError",
     "evalue": "Animal object has no attribute abc",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-78-a143cd822444>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     10\u001b[0m         \u001b[0;32mraise\u001b[0m \u001b[0mAttributeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Animal object has no attribute %s'\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0mattr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     11\u001b[0m \u001b[0ma\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mAnimal\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"hasky\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m90\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 12\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mabc\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# None\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;32m<ipython-input-78-a143cd822444>\u001b[0m in \u001b[0;36m__getattr__\u001b[0;34m(self, attr)\u001b[0m\n\u001b[1;32m      8\u001b[0m         \u001b[0;32melif\u001b[0m \u001b[0mattr\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'age'\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      9\u001b[0m             \u001b[0;32mreturn\u001b[0m \u001b[0;32mlambda\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m25\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 10\u001b[0;31m         \u001b[0;32mraise\u001b[0m \u001b[0mAttributeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Animal object has no attribute %s'\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0mattr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     11\u001b[0m \u001b[0ma\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mAnimal\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"hasky\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;36m90\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     12\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mabc\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# None\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mAttributeError\u001b[0m: Animal object has no attribute abc"
     ]
    }
   ],
   "source": [
    "class Animal():\n",
    "    def __init__(self,name,weight):\n",
    "        self.name = name\n",
    "        self.weight = weight\n",
    "    def __getattr__(self,attr):\n",
    "        if attr == 'height':\n",
    "            return 20\n",
    "        elif attr == 'age':\n",
    "            return lambda: 25\n",
    "        raise AttributeError('Animal object has no attribute %s' % attr)\n",
    "a = Animal(\"hasky\",90)\n",
    "print(a.abc) # AttributeError: Animal object has no attribute abc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
